load("@aspect_rules_js//npm:defs.bzl", "npm_package")
load("//:build/js_capnp_library.bzl", "js_capnp_library")
load("//:build/kj_test.bzl", "kj_test")
load("//:build/wd_cc_capnp_library.bzl", "wd_cc_capnp_library")
load("//:build/wd_cc_library.bzl", "wd_cc_library")

exports_files(["modules.capnp"])

wd_cc_library(
    name = "jsg",
    srcs = [],
    hdrs = [
        "jsg-test.h",
        "type-wrapper.h",
    ],
    local_defines = ["JSG_IMPLEMENTATION"],
    visibility = ["//visibility:public"],
    deps = [
        ":exception",
        ":iterator",
        ":jsg-core",
        ":memory-tracker",
        ":url",
        "//src/workerd/util",
        "//src/workerd/util:sentry",
        "//src/workerd/util:thread-scopes",
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "iterator",
    srcs = [
        "iterator.c++",
    ],
    hdrs = [
        "iterator.h",
        "struct.h",
        "value.h",
    ],
    local_defines = ["JSG_IMPLEMENTATION"],
    deps = [
        ":exception",
        ":jsg-core",
        ":memory-tracker",
        "//src/workerd/util",
        "//src/workerd/util:sentry",
        "//src/workerd/util:thread-scopes",
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "script",
    srcs = ["script.c++"],
    hdrs = ["script.h"],
    local_defines = ["JSG_IMPLEMENTATION"],
    visibility = ["//visibility:public"],
    deps = [
        ":jsg-core",
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

# Subset of JSG that includes core JSG interfaces, but does not depend on type-wrapper API.
# Factoring this out reduces the need for circular includes and will make future refactoring of JSG
# much easier.
# This is only visible in this package for now – to avoid extensive include changes in code using
# the JSG type wrapper, the main JSG target should be used instead for now.
# Avoid adding dependencies or new files to this when possible.
wd_cc_library(
    name = "jsg-core",
    srcs = [
        "async-context.c++",
        "buffersource.c++",
        "dom-exception.c++",
        "jsg.c++",
        "jsvalue.c++",
        "modules.c++",
        "modules-new.c++",
        "promise.c++",
        "resource.c++",
        "ser.c++",
        "setup.c++",
        "util.c++",
        "v8-platform-wrapper.c++",
        "wrappable.c++",
    ],
    hdrs = [
        "async-context.h",
        "buffersource.h",
        "dom-exception.h",
        "fast-api.h",
        "function.h",
        "jsg.h",
        "jsvalue.h",
        "modules.h",
        "modules-new.h",
        "promise.h",
        "resource.h",
        "ser.h",
        "setup.h",
        "util.h",
        "v8-platform-wrapper.h",
        "web-idl.h",
        "wrappable.h",
    ],
    # Some JSG headers can't be compiled on their own
    features = ["-parse_headers"],
    implementation_deps = [
        "//src/workerd/util:entropy",
        "@simdutf",
        "@ssl",
    ],
    local_defines = ["JSG_IMPLEMENTATION"],
    tags = ["no-clang-tidy"],
    deps = [
        ":exception",
        ":exception_metadata_capnp",
        ":macro-meta",
        ":memory-tracker",
        ":meta",
        ":modules_capnp",
        ":observer",
        ":url",
        "//src/workerd/util",  # Required for util/batch-queue.h
        "//src/workerd/util:autogate",
        "//src/workerd/util:sentry",
        "//src/workerd/util:thread-scopes",
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "compile-cache",
    srcs = [
        "compile-cache.c++",
    ],
    hdrs = [
        "compile-cache.h",
    ],
    local_defines = ["JSG_IMPLEMENTATION"],
    visibility = ["//visibility:public"],
    deps = [
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "inspector",
    srcs = [
        "inspector.c++",
    ],
    hdrs = [
        "inspector.h",
    ],
    implementation_deps = [
        ":jsg-core",
        "@capnp-cpp//src/kj",
        "@simdutf",
        "@workerd-v8//:v8",
    ],
    local_defines = ["JSG_IMPLEMENTATION"],
    # Some JSG headers can't be compiled on their own
    visibility = ["//visibility:public"],
)

wd_cc_library(
    name = "memory-tracker",
    srcs = ["memory.c++"],
    hdrs = ["memory.h"],
    visibility = ["//visibility:public"],
    deps = [
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "meta",
    hdrs = ["meta.h"],
    visibility = ["//visibility:public"],
    deps = [
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

wd_cc_library(
    name = "url",
    srcs = ["url.c++"],
    hdrs = [
        "url.h",
    ],
    implementation_deps = [
        "//src/workerd/util:strings",
        "@ada-url",
    ],
    visibility = ["//visibility:public"],
    deps = [
        ":memory-tracker",
        "@capnp-cpp//src/kj",
    ],
)

wd_cc_library(
    name = "exception",
    srcs = ["exception.c++"],
    hdrs = ["exception.h"],
    visibility = ["//visibility:public"],
    deps = [
        "@capnp-cpp//src/kj",
    ],
)

wd_cc_capnp_library(
    name = "rtti_capnp",
    srcs = ["rtti.capnp"],
    visibility = ["//visibility:public"],
)

wd_cc_capnp_library(
    name = "exception_metadata_capnp",
    srcs = ["exception-metadata.capnp"],
    visibility = ["//visibility:public"],
)

js_capnp_library(
    name = "rtti_capnp_js",
    srcs = ["rtti.capnp"],
    outs = [
        "rtti.js",
        "rtti.ts",
    ],
    data = ["//:node_modules/capnp-es"],
    target_compatible_with = select({
        "@platforms//os:windows": ["@platforms//:incompatible"],
        "@//build/config:no_build": ["@platforms//:incompatible"],
        "//conditions:default": [],
    }),
    visibility = ["//visibility:public"],
)

npm_package(
    name = "jsg_js",
    srcs = [":rtti_capnp_js"],
    # Required to ensure source files are copied when running internal builds
    # that depend on `workerd` as an external repository
    include_external_repositories = ["workerd"],
    publishable = False,
    visibility = ["//visibility:public"],
)

wd_cc_library(
    name = "rtti",
    hdrs = ["rtti.h"],
    visibility = ["//visibility:public"],
    deps = [
        ":jsg",
        ":rtti_capnp",
    ],
)

wd_cc_library(
    name = "macro-meta",
    hdrs = ["macro-meta.h"],
    visibility = ["//visibility:public"],
)

wd_cc_capnp_library(
    name = "modules_capnp",
    srcs = ["modules.capnp"],
    visibility = ["//visibility:public"],
)

wd_cc_library(
    name = "observer",
    hdrs = ["observer.h"],
    visibility = ["//visibility:public"],
    deps = [
        "//src/workerd/util:strong-bool",
        "@capnp-cpp//src/kj",
        "@workerd-v8//:v8",
    ],
)

[kj_test(
    src = f,
    local_defines = ["JSG_IMPLEMENTATION"],
    deps = [":jsg"],
) for f in glob(
    ["*-test.c++"],
    exclude = [
        # defined below
        "macro-meta-test.c++",
        "resource-test.c++",
        "rtti-test.c++",
        "url-test.c++",
        "multiple-typewrappers-test.c++",
    ],
)]

# Moved out as macro-meta-test does not depend on V8 or JSG proper, this makes the test much
# smaller.
kj_test(
    src = "macro-meta-test.c++",
    deps = [
        ":macro-meta",
    ],
)

kj_test(
    src = "rtti-test.c++",
    deps = [
        ":rtti",
        ":rtti_test_capnp",
        # TODO: move text encoding out
        "@capnp-cpp//src/capnp:capnpc",
    ],
)

kj_test(
    src = "url-test.c++",
    deps = [
        ":url",
        "@ssl",
    ],
)

wd_cc_capnp_library(
    name = "resource_test_capnp",
    srcs = ["resource-test.capnp"],
    data = glob(["resource-test-*.js"]),
    deps = [":modules_capnp"],
)

wd_cc_capnp_library(
    name = "rtti_test_capnp",
    srcs = ["rtti-test.capnp"],
    deps = [":modules_capnp"],
)

kj_test(
    src = "resource-test.c++",
    deps = [
        ":jsg",
        ":resource_test_capnp",
    ],
)

kj_test(
    src = "multiple-typewrappers-test.c++",
    deps = [
        ":jsg",
        "//src/workerd/io:compatibility-date_capnp",
    ],
)
